import _, { pick as _pick, isEmpty } from 'lodash';
import type { Operator } from '@/components/searchform/operators';
import { allOperators, typeOperators } from '@/components/searchform/operators';
import type {
  SearchField,
  View,
  CompatibilityModeView,
  SupportFilterField,
  SystemFilterItem,
  CustomComponent,
  SmartSearchLocalFilter,
} from '@/components/searchform/interface';
import type { SearchFormSchema } from '../searchform/index';
import type { Multiple } from './index';

// 以mode属性配置多选的组件列表
const MODE_COMPONENTS = ['Selector', 'CodeList'];
// 以multiple属性配置多选的组件列表
const MULTIPLE_COMPONENTS = [
  'UserSelector',
  'GroupSelector',
  'RoleSelector',
  'UserGroupSelector',
  'CodeListSelector',
  'UnitSelector',
];

/**
 * 通过操作符key的列表获取操作符列表
 * @param keys 操作符key的列表
 */
export function getOperatorsByOperateKey(keys: string[]): Operator[] {
  return Object.values(_pick(allOperators, keys));
}

/**
 * 通过数据类型获取对应操作符列表或者操作符key列表
 * @param type 数据类型
 */
export function getOperatorsByDataType(type: string, isKeys: boolean = false) {
  if (isKeys) {
    return typeOperators[type];
  }
  return getOperatorsByOperateKey(typeOperators[type]);
}

/**
 * 通过suppOperator和type获取对应操作符列表
 * @param type 数据类型
 */
export function getOperatorsBySupportAndType(suppOperator: string[], type: string) {
  const operators = suppOperator
    ? _.filter(suppOperator, (item) => _.includes(typeOperators[type], item))
    : typeOperators[type];
  return getOperatorsByOperateKey(operators);
}

/**
 * 获取正常情况初始查询条件
 * @param earchFields 查询字段
 * @param isCompatibilityMode 是否是兼容模式
 */
export function getNormalInitSearchParams(earchFields: SearchField[], isCompatibilityMode = false): any {
  let res = earchFields
    .filter(({ operator = 'EMPTY' }) => ['IS_NOT_NULL', 'IS_NULL'].includes(operator))
    .map((item) => {
      const { fieldName, operator } = item;
      return {
        fieldName,
        operator,
        value: null,
      };
    });
  if (isCompatibilityMode) {
    res = res.reduce((tempRes: any, item: any) => {
      const { fieldName, value } = item;
      tempRes[fieldName] = value;
      return tempRes;
    }, {});
  }
  return res;
}

interface GetSchemaParams {
  multiple: Multiple;
  customComponents: CustomComponent[];
}

/**
 * 获取适用于SearchForm的schema
 * @param supportFilterFields
 * @param searchFields
 */
export function getSchema(
  supportFilterFields: SupportFilterField[],
  searchFields: SearchField[],
  params: GetSchemaParams,
) {
  const schema: any = {};
  const orderKeys: string[] = [];
  const { multiple = {}, customComponents = [] } = params;

  if (isEmpty(supportFilterFields) || isEmpty(searchFields)) return schema;
  const filedsSchema: any = {};
  supportFilterFields.map((fieldItem) => {
    const { type, ...itemField } = fieldItem;
    filedsSchema[fieldItem.fieldName] = {
      ...itemField,
      CUSTOM_TYPE: type,
    };
  });

  // 获取自定义组件配置的多选模式
  const [customModeComponents, customMultipleComponents] = customComponents.reduce(
    (res: [string[], string[]], item) => {
      const { name, multiple } = item;
      if (multiple) {
        // eslint-disable-next-line default-case
        switch (multiple) {
          case 'mode':
            res[0].push(name);
            break;
          case 'multiple':
            res[1].push(name);
            break;
        }
      }
      return res;
    },
    [[], []],
  );
  const { mode = [], multiple: multiple_ = [] } = multiple;
  const modeComponents = MODE_COMPONENTS.concat(mode, customModeComponents);
  const multipleComponents = MULTIPLE_COMPONENTS.concat(multiple_, customMultipleComponents);

  searchFields.map((item) => {
    const { fieldName, operator = undefined } = item;
    const currentFieldObj = filedsSchema[fieldName];
    if (!isEmpty(currentFieldObj)) {
      const fieldName_ = operator ? `${fieldName}:${operator}` : fieldName;
      orderKeys.push(fieldName_);
      let { componentType } = currentFieldObj;
      const addProps = currentFieldObj.props || {};
      const isInOrNotIn = ['IN', 'NOT_IN'].includes(operator);
      let { title } = currentFieldObj;

      if (modeComponents.includes(componentType) && isInOrNotIn) {
        addProps.mode = 'multiple';
      } else if (typeof operator !== 'undefined') {
        delete addProps.mode;
      }

      if (multipleComponents.includes(componentType) && isInOrNotIn) {
        addProps.multiple = true;
      } else if (typeof operator !== 'undefined') {
        delete addProps.mode;
      }

      if (['IS_NULL', 'IS_NOT_NULL'].includes(operator)) {
        componentType = 'SmartSearchSwitch';
      }

      if (operator) {
        const temp = allOperators[operator];
        title = temp ? `${title} (${temp.symbol || temp.name})` : title;
      }

      schema[fieldName_] = {
        ...currentFieldObj,
        operator,
        componentType,
        props: addProps,
        title,
      };
    }
  });

  return [schema, orderKeys];
}

/**
 * 如果某个视图在指定视图列表中，则返回视图列表中的视图，并根据类型设置isSystem属性
 * @param views
 * @param view
 */
export function isViewInViews(
  views: (View | CompatibilityModeView)[] = [],
  view: View | CompatibilityModeView,
  type: 'system' | 'custom',
) {
  const tempView = views.find((item) => {
    const { version, viewId } = item;
    const { version: initVersion, viewId: initViewId } = view;
    return version === initVersion && viewId === initViewId;
  });
  if (tempView) {
    tempView.isSystem = type === 'system';
  }

  return tempView;
}

// 获取searchform schema中的默认值
export function getDefaultParams(schema: SearchFormSchema): SystemFilterItem[] {
  const tempDefaultParams = Object.entries(schema).reduce((res: any, [key, item]: [string, any]) => {
    const { options = {}, fieldName, operator = 'EMPTY' } = item;
    if (options.initialValue) {
      res.push({
        fieldName,
        value: options.initialValue,
        operator,
      });
    }
    return res;
  }, []);

  return tempDefaultParams;
}

/**
 * 判断当前视图的筛选器中是否开启了自动查询
 * @param activeView
 * @param filters
 */
export function checkViewHasAutoSearch(view: View | CompatibilityModeView, filter: SmartSearchLocalFilter) {
  const { viewId, version } = view;
  const filterKey = `${viewId}|${version}`;
  const filters = filter[filterKey] || [];
  return filters.some((filter) => filter.isAutoSearch);
}
